/*
 * string.cpp
 *
 *  Created on: 2016-11-23
 *      Author: work
 */

#include <dm/export.hpp>

#define DM_API_STRING DM_API_EXPORT

#include <dm/string/string.hpp>
#include <cstring>
#include <cstdio>

using namespace std;

namespace dm{
namespace string{

CString::CString():CStringRef(NULL),m_b(NULL){
}

CString::CString( const CString& str ):CStringRef(NULL){
	int l = str.len();
	if( l<=0 )
		m_b = NULL;
	else{
		m_b = new char[l+1];
		str.dump(m_b);
	}

	m_r = m_b;
}

CString::CString( const CStringRef& str ):CStringRef(NULL){
	int l = str.len();
	if( l<=0 )
		m_b = NULL;
	else{
		m_b = new char[l+1];
		str.dump(m_b);
	}

	m_r = m_b;
}

CString::CString( const char* str ):CStringRef(NULL){
	CStringRef r(str);
	int l = r.len();
	if( l<=0 )
		m_b = NULL;
	else{
		m_b = new char[l+1];
		r.dump(m_b);
	}

	m_r = m_b;
}

CString::CString( const char* str,int len ):CStringRef(NULL){
	CStringRef r(str);
	int l = r.len();
	if( l>len )
		l = len;

	if( l<=0 )
		m_b = NULL;
	else{
		m_b = new char[l+1];
		r.dump(m_b,l+1,0,l);
	}

	m_r = m_b;
}

CString::~CString(){
	if( m_b!=NULL )
		delete [] m_b;
}

CString& CString::operator =( const CString& str ){
	if( m_b!=NULL )
		delete [] m_b;

	int l = str.len();
	if( l<=0 )
		m_b = NULL;
	else{
		m_b = new char[l+1];
		str.dump(m_b);
	}

	m_r = m_b;

	return *this;
}

CString& CString::operator =( const CStringRef& str ){
	if( m_b!=NULL )
		delete [] m_b;

	int l = str.len();
	if( l<=0 )
		m_b = NULL;
	else{
		m_b = new char[l+1];
		str.dump(m_b);
	}

	m_r = m_b;
	return *this;
}

CString CString::reverse()const{
	CString r = *this;

	int l = len();
	if( l>1 ){
		--l;
		for( int i=0;i<l;++i,--l ){
			r.m_b[i] = m_b[l];
			r.m_b[l] = m_b[i];
		}
	}

	return r;
}

CString CString::operator+( const CStringRef& ref )const{
	CString r;

	int ll = len();
	int ls = ref.len();

	if( ll+ls>0 ){
		r.m_b = new char[ll+ls+1];
		r.m_r = r.m_b;
		dump(r.m_b);
		ref.dump(r.m_b+ll);
	}

	return r;
}

CString CString::operator+( const CString& str )const{
	CString r;

	int ll = len();
	int ls = str.len();

	if( ll+ls>0 ){
		r.m_b = new char[ll+ls+1];
		r.m_r = r.m_b;
		dump(r.m_b);
		str.dump(r.m_b+ll);
	}

	return r;
}

CString CString::sub( int start,int size )const{
	CString rt;
	if( size==-1 )
		size = len() - start;

	if( size>0 && start+size<=len() ){
		rt.m_b = new char[size+1];
		rt.m_r = rt.m_b;
		dump(rt.m_b,size+1,start,size);
	}

	return rt;
}

CString CString::trimed()const{
	if( len()==0 )
		return CString();

	int s = nextNoneChars(" \t\r\n");
	if( s==-1 )
		return CString();

	int e = lastNoneChars(" \t\r\n");

	return CString(m_r+s,e-s+1);
}

CString CString::fromHex( dm::uint8 v ){
	CString rt("FF");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(),"%02X", v);
#else
	std::sprintf(rt.m_b,"%02X",v);
#endif
	return rt;
}

CString CString::fromUint8( dm::uint8 v ){
	CString rt("255");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(), "%d", v);
#else
	std::sprintf(rt.m_b,"%d",v);
#endif
	return rt;
}

CString CString::fromInt8( dm::int8 v ){
	CString rt("-128");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(), "%d", v);
#else
	std::sprintf(rt.m_b,"%d",v);
#endif
	return rt;
}

CString CString::fromUint16( dm::uint16 v ){
	CString rt("65535");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(), "%d", v);
#else
	std::sprintf(rt.m_b,"%d",v);
#endif
	return rt;
}

CString CString::fromInt16( dm::int16 v ){
	CString rt("-32767");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(),"%d",v);
#else
	std::sprintf(rt.m_b, "%d", v);
#endif
	return rt;
}

CString CString::fromUint32( dm::uint32 v ){
	CString rt("4294967295");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(),"%d",v);
#else
	std::sprintf(rt.m_b, "%d", v);
#endif
	return rt;
}

CString CString::fromInt32( dm::int32 v ){
	CString rt("-2147483647");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(),"%d",v);
#else
	std::sprintf(rt.m_b, "%d", v);
#endif
	return rt;
}

CString CString::fromUint64( dm::uint64 v ){
	CString rt("18446744073709551615");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(),"%llu",v);
#else
	std::sprintf(rt.m_b, "%llu", v);
#endif
	return rt;
}

CString CString::fromInt64( dm::int64 v ){
	CString rt("-9223372036854775807");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(),"%lld",v);
#else
	std::sprintf(rt.m_b, "%lld", v);
#endif
	return rt;
}

CString CString::fromFloat32( dm::float32 v ){
	CString rt("01234567890123456789");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(), "%f", v);
#else
	std::sprintf(rt.m_b,"%f",v);
#endif
	return rt;
}

CString CString::fromFloat64( dm::float64 v ){
	CString rt("01234567890123456789");
#ifdef WIN32
	sprintf_s(rt.m_b,rt.len(), "%f", v);
#else
	std::sprintf(rt.m_b,"%f",v);
#endif
	return rt;
}

}
}


